﻿//
//
// 版权所有 (c) 2021-2023 JR  
//
// 特此免费授予获得本软件的任何人以处理本软件的权利，但须遵守以下条件：在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
//
// 软件按“原样”提供，不提供任何形式的明示或暗示的保证，包括但不限于对适销性、适用性和非侵权的保证。
// 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他责任负责，无论是因合同、侵权或其他方式引起的，与软件或其使用或其他交易有关。

using Mapster;
using EMC.VISITOR.Core;
using SapNwRfc;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinGetCurrentSelfMenuInfoResponse.Types.Menu.Types.Button.Types;

namespace EMC.VISITOR.Core;
public interface IErpFilter
{
    string ErpId { get; set; }
}

public interface IHistory
{
     
}

public abstract class EntityBaseDataErp : EntityBaseData, IErpFilter
{
    [SapName("ErpId")]
    [JsonProperty("ErpId")]
    [SugarColumn(IsNullable = true, ColumnDescription = "ErpId", IndexGroupNameList = new string[] { "index_erpid" }, IsOnlyIgnoreUpdate = true)]
    public virtual string ErpId { get; set; }

}

public abstract class EntityBaseDataErp2 : EntityBaseData, IErpFilter
{
    [SapName("ErpId")]
    [JsonProperty("ErpId")]
    [SugarColumn(IsNullable = true, ColumnDescription = "ErpId")]
    public virtual string ErpId { get; set; }

}

public class OtherSystem : EntityBaseDataErp
{
    /// <summary>
    /// 第三方系统修改时间
    /// </summary>
    //[SapName("WRITEDATE")]
    [SugarColumn(IsNullable = true, ColumnDescription = "第三方系统修改时间")]
    public DateTime? WriteDate { get; set; }
}

public interface IOtherSystemInterface
{

}
/// <summary>
/// 其它系统接口
/// </summary>
public abstract class OtherSystemAsync<SapEntity, DbEntity> where SapEntity : OtherSystem, new() where DbEntity : EntityBaseDataErp, new()
{

    /// <summary>
    /// 数据同步
    /// </summary>
    /// <param name="list">SAP数据集合</param>
    /// <param name="saveData">字符串 True :新增、修改本地数据   False：不新增、不修改本地数据</param>
    /// <param name="_db">数据库上下文</param>
    /// <param name="ignoreColumnList">修改时需要忽略的MES字段</param>
    /// <returns></returns>
    public async Task AsyncDataOperation(List<SapEntity> list, string saveData, ISqlSugarClient _db, string[] ignoreColumnList)
    {
        if (list == null || list.Count == 0)
        {
            await Task.CompletedTask;
            return;
        }
        var mapsterTo = new TypeAdapterConfig();
        mapsterTo.ForType<SapEntity, DbEntity>().IgnoreNullValues(true).IgnoreAttribute(typeof(ErpToMESMapperIgnoreAttribute));
        var newList = list.Select(r => r.Adapt<DbEntity>(mapsterTo)).ToList();
        //同步保存到MES系统
        int pageSize = App.GetConfig<int>("MaxAsyncCount");
        //是否保存第三方系统数据
        bool isSaveOtherSystemData = App.GetConfig<bool>("IsSaveOtherSystemData");
        var TotalPages = (int)Math.Ceiling(newList.Count / (double)pageSize);
        for (int currentPage = 1; currentPage <= TotalPages; currentPage++)
        {
            //每次插入或更新数据 2000 条
            var skip = (currentPage - 1) * pageSize;
            #region 更新业务数据表
            var tempList = newList.Skip(skip).Take(pageSize).ToList();
            //本地数据库存在的数据，表示是旧数据，更新数据
            var localExistList = await _db.Queryable<DbEntity>().Where(r => tempList.Select(c => c.ErpId).Contains(r.ErpId))
                //.Select(r => r.ErpId)
                .ToListAsync();
            if (localExistList.Count() > 0)
            {
                //ERP这次传过来并且存在咱们系统的数据
                var ErpComeDataList = tempList.Where(r => localExistList.Select(c => c.ErpId).Contains(r.ErpId)).ToList();
                ErpComeDataList = await EditClearCurrentSystemData(localExistList, ErpComeDataList, _db, "update");
                if (ErpComeDataList.Count() > 0 && saveData.ObjToBool())
                {
                    await _db.MyUpdateable(ErpComeDataList).WhereColumns(r => new { r.ErpId })
                        .IgnoreColumns(true, false, true)
                        .IgnoreColumns(ignoreColumnList)
                        .IgnoreColumns(r => r.Id).ExecuteCommandAsync();
                }
            }
            //不在数据库里的数据，表示是新的数据,插入数据
            var notExistdbDataList = tempList.Where(r => !localExistList.Select(c => c.ErpId).Contains(r.ErpId)).ToList();
            if (notExistdbDataList.Count() > 0)
            {
                notExistdbDataList = await EditClearCurrentSystemData(null, notExistdbDataList, _db, "add");
                if (notExistdbDataList.Count() > 0 && saveData.ObjToBool())
                    await _db.MyInsertable(notExistdbDataList).ExecuteCommandAsync();
            }
            #endregion

            #region 更新第三方数据表
            if (isSaveOtherSystemData)
            {
                var sapTempList = list.Skip(skip).Take(pageSize).ToList();
                var sapErpIds = sapTempList.Select(c => c.ErpId).ToList();
                //本地数据库存在的数据，表示是旧数据，更新数据
                var sapLocalExistList = await _db.Queryable<SapEntity>().Where(r => sapErpIds.Contains(r.ErpId)).Select(z => z.ErpId).ToListAsync();
                if (sapLocalExistList.Count() > 0)
                {
                    var sapErpComeDataList = sapTempList.Where(r => sapLocalExistList.Contains(r.ErpId)).ToList();
                    if (sapErpComeDataList.Count() > 0)
                        await _db.MyUpdateable(sapErpComeDataList)
                            .WhereColumns(r => new { r.ErpId })
                        .IgnoreColumns(r => r.Id).ExecuteCommandAsync();
                }
                //不在数据库里的数据，表示是新的数据,插入数据
                var sapNotExistdbDataList = sapTempList.Where(r => !sapLocalExistList.Contains(r.ErpId)).ToList();
                if (sapNotExistdbDataList.Count() > 0)
                {
                    await _db.MyInsertable(sapNotExistdbDataList).ExecuteCommandAsync();
                }
            }
            #endregion
        }
    }
    /// <summary>
    /// 清洗本系统数据
    /// </summary>
    /// <param name="localExistList">当前系统数据库中可能存在的数据集合【当operationType=="add" 此数据为空】</param>
    /// <param name="list">本次ERP系统传输过来的数据</param>
    /// <param name="_db">数据库上下文</param>
    /// <param name="operationType">操作类型：update,add</param>
    /// <returns></returns>
    protected abstract Task<List<DbEntity>> EditClearCurrentSystemData(List<DbEntity> localExistList, List<DbEntity> list, ISqlSugarClient _db, string operationType);
}
